// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import Utils from "./Utils";

const {ccclass, property} = cc._decorator;
/**
 * 主游戏类
 * 管理准备和玩游戏两个节点
 */
@ccclass
export default class Game extends cc.Component {

    // 准备界面节点
    @property(cc.Node)
    nodeReady: cc.Node = null;

    // 玩游戏界面节点
    @property(cc.Node)
    nodePlaying: cc.Node = null;

    // 玩游戏界面下 - 游戏场景父节点
    @property(cc.Node)
    blockParent: cc.Node = null

    // 盒子节点预制体，背景
    @property(cc.Prefab)
    preBgBlock: cc.Prefab = null

    // 盒子节点预制体，精灵
    @property(cc.Prefab)
    preBlock: cc.Prefab = null

    // 盒子格子间的间隙
    rectGap: number = 2
    rectWH: number = 110

    // 添加的区块
    blockArr: Object = null

    // 区块精灵图片
    @property([cc.SpriteFrame])
    spfBlockArr: Array<cc.SpriteFrame> = []

    // 第几关
    blockLevel: number = 1

    // 添加方块
    addBlock_test(){
        // 设置默认背景方块宽高
        this.blockParent.width = this.rectWH * 6 + this.rectGap * 7
        this.blockParent.height = this.rectWH * 6 + this.rectGap * 7
        // 因为坐标原点在0.5，0.5，所以 width / 2 = 一半的长度
        // 半长度加上负数 - ，例如得出结果时 - 337，那么该点位置就是 - 337，-337
        // 该精灵的坐标就是在原有图形的左下角的点上
        let parentPos = cc.v2(-this.blockParent.width / 2, -this.blockParent.height / 2)
        
        // 做一个6*6的方块
        for (let i = 0; i < 6; i++) {
            for (let j = 0; j < 6; j++) {
                // 克隆一个预制体
                let blockNode = cc.instantiate(this.preBgBlock)
                blockNode.parent = this.blockParent
                blockNode.width = this.rectWH
                blockNode.height = this.rectWH
                blockNode.opacity = 100
                blockNode.getChildByName('lbl').getComponent(cc.Label).string = `${i},${j}`

                // 计算预制体的坐标
                let blockNodePos = cc.v2(
                    // 左下角起点 + 方块的一半宽（为什么一半？因为方块的原点起始时0.5，0.5） + 间隙值（计算得出） + 起步间隙
                    // - 337 + 110 / 2 + 2 * i + 2 * i + 2
                    parentPos.x + this.rectWH / 2 + this.rectWH * i + this.rectGap * i + this.rectGap, 
                    parentPos.y + this.rectWH / 2 + this.rectWH * j + this.rectGap * j + this.rectGap, 
                )
                // 设置预制体的位置
                blockNode.setPosition(
                    blockNodePos
                )
            }
        }
      
    }

    // 添加方块
    addBlock(str:string){
        let block = cc.instantiate(this.preBlock)
        block.parent = this.blockParent
        block.width = this.blockArr[str].w
        block.height = this.blockArr[str].h
        block.attr({blockType:str})
        block.getComponent(cc.Sprite).spriteFrame = this.blockArr[str].spf
     }

    // 初始化函数
    initConf(){
        this.blockArr  = {
            '1_2': {
                w:108,
                h:220,
                spf: this.spfBlockArr[0]
            },
            '1_3': {
                w:108,
                h:332,
                spf: this.spfBlockArr[1]
            },
            '2_1': {
                w:220,
                h:108,
                spf: this.spfBlockArr[2]
            },
            '3_1': {
                w:332,
                h:108,
                spf: this.spfBlockArr[3]
            },
        }
    }

    // 添加块元素
    initBlock(){
        let self = this
        
        let arrBlockType = Utils.getMount('gameDate').arrBlockType[this.blockLevel - 1]
        let arrPos = Utils.getMount('gameDate').arrPos[this.blockLevel - 1]

        for (let index = 0; index < arrBlockType.length; index++) {
            const strBlockType = arrBlockType[index];
            const pos = arrPos[index];

            {
                let block = cc.instantiate(self.preBlock)
                block.parent = self.blockParent
                block.width = self.blockArr[strBlockType].w
                block.height = self.blockArr[strBlockType].h
                block.attr({blockType:strBlockType})
                block.getComponent(cc.Sprite).spriteFrame = self.blockArr[strBlockType].spf
                block.setPosition(pos)

                let posBlock = cc.v2(pos.x * ( this.rectWH + this.rectGap), pos.y * ( this.rectWH + this.rectGap ))
            
                block.setPosition(this.getPosZXJ(posBlock))
            }
        }
    }

    getPosZXJ(posParent){
        var posBegin = cc.v2(-this.blockParent.width / 2 + this.rectGap, -this.blockParent.width / 2+ this.rectGap)
        var posZXJ = cc.v2(posBegin.x  + posParent.x, posBegin.y + posParent.y)
        return posZXJ
    }

    // 打印方块位置
    logStr(str){
        let blockNodes = this.blockParent.children
        let arrBlockType = []
        let arrPos = []
        for (let index = 0; index < blockNodes.length; index++) {
            let block = blockNodes[index]
            
            if (block.name == 'block'){
                // console.log(block['xx'],block['yy']);
                // console.log(block['blockType']);
                arrBlockType.push(block['blockType'])
                arrPos.push('cc.v2('+block['xx']+', '+ block['yy'] +')')
            }
        }   
        console.log("['"+arrBlockType.join("','")+"']");
        console.log('['+arrPos.toString()+']');
    }

    clearBlock(str){
        for (let index = this.blockParent.children.length - 1; 0 <= index; index--) {
            const element = this.blockParent.children[index];
            console.log(element);
            
            if (element.name == 'block') {
                element.removeFromParent(true)
            }
        }
    }

    // 界面上的点击事件处理
    btnClick(sender, str){
        // 判断按钮
        if (str == 'btnPlay') {  // 玩游戏事件
            this.nodeReady.active = false   // 隐藏准备界面
            this.nodePlaying.active = true      // 大可以游戏界面
        }else if(str == 'btnHomePlaying'){  // 返回主页事件
            this.nodeReady.active = true        // 显准备界面
            this.nodePlaying.active = false     // 隐藏游戏界面
        }else if(Object.keys(this.blockArr).includes(str)){
            this.addBlock(str)
        }else if(str == 'clear'){
            this.clearBlock(str)
        }else if(str == 'log'){
           this.logStr(str)
        }else{
            this.actionMenu(str)            // 其他按钮事件
        }
        cc.log('点击事件：',str)
    }

    // 其他按钮事件
    actionMenu(str: string){
        // 获取按钮组的父节点
        let nodeBtn = this.nodePlaying.getChildByName('nodeBtn')
        if (str == 'btnClosePlaying') { // 关闭按钮组事件
            // 显示按钮组
            nodeBtn.getChildByName('btnMenuPlaying').active = true  
            // 隐藏关闭按钮
            nodeBtn.getChildByName('btnClosePlaying').active = false    

            // 获取按钮组节点
            let btnMenu = nodeBtn.getChildByName('btnMenuPlaying')
            // 获取按钮组节点的坐标
            let posBtnMenu = cc.v2(btnMenu.x, btnMenu.y)

            // 执行按钮组的所有动画
            cc.tween(nodeBtn.getChildByName('btnHomePlaying')).to(0.1, {  // 按钮组主页
                position: cc.v3(posBtnMenu.x, posBtnMenu.y), // 按钮坐标位于主按钮组
                opacity: 0                                   // 该按钮透明度，
            }).call(() => { 
                nodeBtn.getChildByName('btnHomePlaying').active = false  // 动画执行完成时，实现按钮不可见
            }).start()

            cc.tween(nodeBtn.getChildByName('btnLevelPlaying')).to(0.2, {
                position: cc.v3(posBtnMenu.x, posBtnMenu.y),
                opacity: 0
            }).call(() => { 
                nodeBtn.getChildByName('btnLevelPlaying').active = false
            }).start()

            cc.tween(nodeBtn.getChildByName('btnSkinPlaying')).to(0.3, {
                position: cc.v3(posBtnMenu.x, posBtnMenu.y),
                opacity: 0
            }).call(() => { 
                nodeBtn.getChildByName('btnSkinPlaying').active = false
            }).start()

            cc.tween(nodeBtn.getChildByName('btnSettingPlaying')).to(0.4, {
                position: cc.v3(posBtnMenu.x, posBtnMenu.y),
                opacity: 0
            }).call(() => { 
                nodeBtn.getChildByName('btnSettingPlaying').active = false
                // 当最后一个按钮的隐藏动画完成时，执行如下，显示其余主按钮组
                nodeBtn.getChildByName('btnHitPlaying').active = true
                nodeBtn.getChildByName('btnReplayPlaying').active = true
            }).start()
          

        }else if(str == 'btnMenuPlaying'){  // 打开按钮组
            // 获取按钮组坐标
            let btnMenu = nodeBtn.getChildByName('btnMenuPlaying')
            
            let posBtnMenu = cc.v2(btnMenu.x, btnMenu.y)

            // 根据主按钮组的按钮，计算得出按钮组需要隔开的间隙
            let gap = Math.abs(btnMenu.x) / 2

            // 切换按钮组显示
            nodeBtn.getChildByName('btnMenuPlaying').active = false  // 1. 大按钮1隐藏
            nodeBtn.getChildByName('btnClosePlaying').active = true  // 大按钮close图标显示
            nodeBtn.getChildByName('btnHitPlaying').active = false   // 2. 大按钮2隐藏
            nodeBtn.getChildByName('btnReplayPlaying').active = false// 3. 大按钮3隐藏

            // 执行显示小按钮组动画
            cc.tween(nodeBtn.getChildByName('btnHomePlaying')).to(0.1, {
                position: cc.v3(posBtnMenu.x + gap, posBtnMenu.y), // x坐标为大按钮的x+x的一半值
                opacity: 255
            }).call(() => { 
                nodeBtn.getChildByName('btnHomePlaying').active = true
            }).start()

            cc.tween(nodeBtn.getChildByName('btnLevelPlaying')).to(0.2, {
                position: cc.v3(posBtnMenu.x + gap * 2, posBtnMenu.y),
                opacity: 255
            }).call(() => { 
                nodeBtn.getChildByName('btnLevelPlaying').active = true
            }).start()

            cc.tween(nodeBtn.getChildByName('btnSkinPlaying')).to(0.3, {
                position: cc.v3(posBtnMenu.x + gap * 3, posBtnMenu.y),
                opacity: 255
            }).call(() => { 
                nodeBtn.getChildByName('btnSkinPlaying').active = true
            }).start()

            cc.tween(nodeBtn.getChildByName('btnSettingPlaying')).to(0.4, {
                position: cc.v3(posBtnMenu.x + gap * 4, posBtnMenu.y),
                opacity: 255
            }).call(() => { 
                nodeBtn.getChildByName('btnSettingPlaying').active = true
            }).start()

           
        }
    }

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        // 赋值当前场景给全局变量
        Utils.GlobalMount('game', this)
        
        
        // 加载时，隐藏掉玩游戏场景
        this.nodePlaying.active = false

        // 初始化参数
        this.initConf()

        // 构建游玩界面背景
        this.addBlock_test()

        // 构建配置好的块元素
        this.initBlock()
        
    }

    start () {

    }

    // update (dt) {}
}
